﻿#region File Description
//-----------------------------------------------------------------------------
// Game1.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Threading;
using System.ComponentModel;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


using Nuclex.UserInterface;
using Nuclex.UserInterface.Controls.Desktop;
using Nuclex.UserInterface.Visuals.Flat;
using Nuclex.Input;



namespace IsisCubeDemo
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class IsisCubeClient : Microsoft.Xna.Framework.Game
    {
        GameComponent a;
        

        private const float CAMERA_FOV = 90.0f;
        private const float CAMERA_ZNEAR = 0.01f;
        private const float CAMERA_ZFAR = 500.0f;
        private const float CAMERA_OFFSET = 150.0f;
        


        private CameraComponent camera;
        private SpriteBatch spriteBatch;
        private SpriteFont spriteFont;
        
        private Model box;
        private Texture2D boxTexture;
        
        private Vector2 scaleBias;
        private Vector2 fontPos;
        private Quaternion modelOrientation;
        private Vector3 modelPosition;
        private KeyboardState currentKeyboardState;
        private KeyboardState prevKeyboardState;
        private int windowWidth;
        private int windowHeight;
        private int col;
        private int row;
        private int maxCol;
        private int maxRow;
        private int frames;
        private int framesPerSecond;
        private TimeSpan elapsedTime = TimeSpan.Zero;
        private bool displayHelp;
        private bool disableColorMap;
        private bool disableParallax;


        /// <summary>Initializes and manages the graphics device</summary>
        private GraphicsDeviceManager graphics;
        /// <summary>Manages the graphical user interface</summary>
        private GuiManager gui;
        private Screen mainScreen;
        /// <summary>Manages input devices for the game</summary>
        private InputManager input;

        private IsisNode isisNode;

        private bool enableDemo ;

        static BackgroundWorker guiWorker;
        static BackgroundWorker guiWorker1;
        SceneManager sceneManager;

        Random random = new Random();

        public IsisCubeClient(int row, int maxRow, int col, int maxCol)
        {


            
            Content.RootDirectory = "Content";

            camera = new CameraComponent(this);
            Components.Add(camera);

            Window.Title = "Isis2 Cube Demo";
            IsFixedTimeStep = false;
            

            this.graphics = new GraphicsDeviceManager(this);
            this.input = new InputManager(Services, Window.Handle);
            this.gui = new GuiManager(Services);
            this.sceneManager = new SceneManager(this);
            this.isisNode = new IsisNode(this);
            // Automatically query the input devices once per update
            Components.Add(this.input);
            Components.Add(this.isisNode);
            // You can either add the GUI to the Components collection to have it render
            // automatically, or you can call the GuiManager's Draw() method yourself
            // at the appropriate place if you need more control.
            Components.Add(this.gui);
            this.gui.DrawOrder = 1000;
            Components.Add(this.sceneManager);
            IsMouseVisible = true;
            enableDemo = false;
            this.row = row;
            this.col = col;
            this.maxRow = maxRow;
            this.maxCol = maxCol;
        }

        protected override void Initialize()
        {
            System.Windows.Forms.Form f = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(this.Window.Handle);
            windowWidth = (GraphicsDevice.DisplayMode.Width - (System.Windows.Forms.SystemInformation.BorderSize.Width+System.Windows.Forms.SystemInformation.FixedFrameBorderSize.Width )* 2*maxRow) / maxRow;
            windowHeight = (GraphicsDevice.DisplayMode.Height - (System.Windows.Forms.SystemInformation.CaptionHeight +(System.Windows.Forms.SystemInformation.BorderSize.Height+ System.Windows.Forms.SystemInformation.FixedFrameBorderSize.Height)*2) * maxCol) / maxCol;
            
            
            
            
            // Setup frame buffer.
            graphics.SynchronizeWithVerticalRetrace = false;
            graphics.PreferredBackBufferWidth = windowWidth;
            graphics.PreferredBackBufferHeight = windowHeight;
            graphics.PreferMultiSampling = true;
            graphics.ApplyChanges();

            // Setup the camera.
            InitCamera();

            // Initial position for text rendering.
            fontPos = new Vector2(1.0f, 1.0f);

            
            // Parallax mapping height scale and bias values.
            scaleBias = new Vector2(0.04f, -0.03f);

            // Initial color for the cube
            //cubeColor = new Vector3(0.0f, 0.0f, 1.0f);

            // Create a new screen. Screens manage the state of a GUI and accept input
            // notifications. If you have an in-game computer display where you want
            // to use a GUI, you can create a second screen for that and thus cleanly
            // separate the state of the in-game computer from your game's own GUI :)
            Viewport viewport = GraphicsDevice.Viewport;
            mainScreen = new Screen(viewport.Width, viewport.Height);
            this.gui.Screen = mainScreen;

            // Each screen has a 'desktop' control. This invisible control by default
            // stretches across the whole screen and serves as the root of the control
            // tree in which all visible controls are managed. All controls are positioned
            // using a system of fractional coordinates and pixel offset coordinates.
            // We now adjust the position of the desktop window to prevent GUI or HUD
            // elements from appearing outside of the title-safe area.
            mainScreen.Desktop.Bounds = new UniRectangle(
              new UniScalar(0.1f, 0.0f), new UniScalar(0.1f, 0.0f), // x and y = 10%
              new UniScalar(0.8f, 0.0f), new UniScalar(0.8f, 0.0f) // width and height = 80%
            );
            
            


            // Create an instance of the demonstration dialog and add it to the desktop
            // control, which means it will become visible and interactive.
            //mainScreen.Desktop.Children.Add(new DemoDialog());

            // Now let's do something funky: add buttons directly to the desktop.
            // This will also show the effect of the title-safe area.
            createDesktopControls(mainScreen);

            // Setup the initial input states.
            currentKeyboardState = Keyboard.GetState();


            
            guiWorker = new BackgroundWorker();
            guiWorker1 = new BackgroundWorker();

            base.Initialize();

            f = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(this.Window.Handle);
            f.Location = new System.Drawing.Point(
                (System.Windows.Forms.SystemInformation.BorderSize.Width + System.Windows.Forms.SystemInformation.FixedFrameBorderSize.Width)
                +(windowWidth + (System.Windows.Forms.SystemInformation.BorderSize.Width + System.Windows.Forms.SystemInformation.FixedFrameBorderSize.Width) * 2)
                * row,
                (windowHeight + System.Windows.Forms.SystemInformation.CaptionHeight + (System.Windows.Forms.SystemInformation.BorderSize.Height + System.Windows.Forms.SystemInformation.FixedFrameBorderSize.Height) * 2) * col);
                 
        }
        
        private void InitCamera()
        {
            GraphicsDevice device = graphics.GraphicsDevice;
            float aspectRatio = (float)windowWidth / (float)windowHeight;
            
            camera.Perspective(CAMERA_FOV, aspectRatio, CAMERA_ZNEAR, CAMERA_ZFAR);
            camera.Position = new Vector3(CAMERA_OFFSET, CAMERA_OFFSET, CAMERA_OFFSET);
            camera.Acceleration = new Vector3(15.0f, 15.0f, 15.0f);
            camera.Velocity = new Vector3(50.0f, 50.0f, 50.0f);
            camera.OrbitMinZoom = 1.5f;
            camera.OrbitMaxZoom = 5.0f;
            camera.OrbitOffsetDistance = camera.OrbitMinZoom;
            ChangeCameraBehavior(Camera.Behavior.Spectator);
            camera.ClickAndDragMouseRotation = !camera.ClickAndDragMouseRotation;
            camera.LookAt(new Vector3(CAMERA_OFFSET, CAMERA_OFFSET, CAMERA_OFFSET), Vector3.Zero, Vector3.Up);
            
            
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>a
        protected override void LoadContent()
        {           
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Load the sprite font. The sprite font has a 3 pixel outer glow
            // baked into it so we need to decrease the spacing so that the
            // SpriteFont will render correctly.

            spriteFont = Content.Load<SpriteFont>(@"Fonts\Arial-Bold-12pt-OuterGlow-3px");
            spriteFont.Spacing = -4.0f;
        }


        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == 
                ButtonState.Pressed)
            {
                this.Exit();
            }
            

            base.Update(gameTime);
            ProcessInput();
            UpdateFrameRate(gameTime);
        }
        private void UpdateFrameRate(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime;

            if (elapsedTime > TimeSpan.FromSeconds(1))
            {
                elapsedTime -= TimeSpan.FromSeconds(1);
                framesPerSecond = frames;
                frames = 0;
            }
        }

        private void IncrementFrameCounter()
        {
            ++frames;
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.SteelBlue);
            DrawText();
            base.Draw(gameTime);
            IncrementFrameCounter();
        }

        
        
        private void ChangeCameraBehavior(Camera.Behavior behavior)
        {
            if (camera.CurrentBehavior == behavior)
                return;

            if (behavior == Camera.Behavior.Orbit)
            {
                modelPosition = camera.Position;
                modelOrientation = Quaternion.Inverse(camera.Orientation);
            }

            camera.CurrentBehavior = behavior;

            // Position the camera behind and 30 degrees above the target.
            if (behavior == Camera.Behavior.Orbit)
                camera.Rotate(0.0f, -30.0f, 0.0f);
        }
        private bool KeyJustPressed(Keys key)
        {
            return currentKeyboardState.IsKeyDown(key) && prevKeyboardState.IsKeyUp(key);
        }
        private void ProcessInput()
        {
            prevKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            if (KeyJustPressed(Keys.Escape))
                this.Exit();

            if (KeyJustPressed(Keys.Back))
            {
                switch (camera.CurrentBehavior)
                {
                    case Camera.Behavior.Flight:
                        camera.UndoRoll();
                        break;

                    case Camera.Behavior.Orbit:
                        if (!camera.PreferTargetYAxisOrbiting)
                            camera.UndoRoll();
                        break;

                    default:
                        break;
                }
            }

            if (KeyJustPressed(Keys.Space))
            {
                if (camera.CurrentBehavior == Camera.Behavior.Orbit)
                    camera.PreferTargetYAxisOrbiting = !camera.PreferTargetYAxisOrbiting;
            }

            if(KeyJustPressed(Keys.O))
                camera.LookAt(new Vector3(CAMERA_OFFSET, CAMERA_OFFSET, CAMERA_OFFSET), Vector3.Zero, Vector3.Up);
            if (KeyJustPressed(Keys.X))
                camera.LookAt(new Vector3(CAMERA_OFFSET*2, 0.0f, 0.0f), Vector3.Zero, Vector3.Up);
            if (KeyJustPressed(Keys.Y))
                camera.LookAt(new Vector3(0.0f, CAMERA_OFFSET*2, 0.0f), Vector3.Zero, -Vector3.Forward);
            if (KeyJustPressed(Keys.Z))
                camera.LookAt(new Vector3(0.0f, 0.0f, CAMERA_OFFSET*2), Vector3.Zero, Vector3.Up);

            if (KeyJustPressed(Keys.D1))
                ChangeCameraBehavior(Camera.Behavior.FirstPerson);

            if (KeyJustPressed(Keys.D2))
                ChangeCameraBehavior(Camera.Behavior.Spectator);

            if (KeyJustPressed(Keys.D3))
                ChangeCameraBehavior(Camera.Behavior.Flight);

            if (KeyJustPressed(Keys.D4))
                ChangeCameraBehavior(Camera.Behavior.Orbit);

            if (KeyJustPressed(Keys.H))
                displayHelp = !displayHelp;

            if (KeyJustPressed(Keys.P))
                disableParallax = !disableParallax;

            if (KeyJustPressed(Keys.T))
                disableColorMap = !disableColorMap;

            if (KeyJustPressed(Keys.C))
                camera.ClickAndDragMouseRotation = !camera.ClickAndDragMouseRotation;

            if (KeyJustPressed(Keys.Add))
            {
                camera.RotationSpeed += 0.01f;

                if (camera.RotationSpeed > 1.0f)
                    camera.RotationSpeed = 1.0f;
            }

            if (KeyJustPressed(Keys.Subtract))
            {
                camera.RotationSpeed -= 0.01f;

                if (camera.RotationSpeed <= 0.0f)
                    camera.RotationSpeed = 0.01f;
            }

            if (currentKeyboardState.IsKeyDown(Keys.LeftAlt) ||
                currentKeyboardState.IsKeyDown(Keys.RightAlt))
            {
                if (KeyJustPressed(Keys.Enter))
                    ToggleFullScreen();
            }
        }
        private void ToggleFullScreen()
        {
            int newWidth = 0;
            int newHeight = 0;

            graphics.IsFullScreen = !graphics.IsFullScreen;

            if (graphics.IsFullScreen)
            {
                newWidth = GraphicsDevice.DisplayMode.Width;
                newHeight = GraphicsDevice.DisplayMode.Height;
            }
            else
            {
                newWidth = windowWidth;
                newHeight = windowHeight;
            }

            graphics.PreferredBackBufferWidth = newWidth;
            graphics.PreferredBackBufferHeight = newHeight;
            graphics.PreferMultiSampling = true;
            graphics.ApplyChanges();

            float aspectRatio = (float)newWidth / (float)newHeight;

            camera.Perspective(CAMERA_FOV, aspectRatio, CAMERA_ZNEAR, CAMERA_ZFAR);
        }

        /// <summary>
        /// Draws the 3D specified model.
        /// </summary>
        /// <param name="model">The 3D model being drawn.</param>
        /// <param name="world">Transformation matrix for world coords.
        /// </param>
        /// <param name="texture">Texture used for the drawn 3D model.
        /// </param>
        void DrawModel(Model model, Matrix world, Texture2D texture, float alpha)
        {
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect be in mesh.Effects)
                {
                    be.EnableDefaultLighting();
                    be.Projection = camera.ProjectionMatrix;
                    be.View = camera.ViewMatrix;
                    be.World = world;
                    be.Texture = texture;
                    //be.TextureEnabled = true;
                    be.Alpha = alpha;
                }
                mesh.Draw();
            }
        }

        private void DoWork_WriteLog(object sender, EventArgs arguments)
        {
            isisNode.WriteLog();
        }
        private void CompletedWork_WriteLog(object sender, RunWorkerCompletedEventArgs e)
        {
            guiWorker.DoWork -= new DoWorkEventHandler(DoWork_WriteLog);
            guiWorker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(CompletedWork_WriteLog);
        }
        private void DoWork_JoinIsisGroup(object sender, EventArgs arguments)
        {
            DisableButtons(new int[] {0}); //except write log button
            isisNode.JoinIsisGroup();
        }
        private void CompletedWork_JoinIsisGroup(object sender, RunWorkerCompletedEventArgs e)
        {

            guiWorker.DoWork -= new DoWorkEventHandler(DoWork_JoinIsisGroup);
            guiWorker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(CompletedWork_JoinIsisGroup);
            EnableButtons(null);
        }
        
        private void DoWork_StartDemo(object sender, EventArgs arguments)
        {
            DisableButtons(new int[] { 0,3 }); //except write log button
            enableDemo = true;
            lock(isisNode.sceneStateLock){
                while(!isisNode.stateMsgRcvd){
                    Monitor.Wait(isisNode.sceneStateLock); 
                }
                int ran = random.Next(1, 10000);
                if (ran >9990)
                {
                    sceneManager.CreateRandomBall(Vector3.Zero);
                }
                else
                    sceneManager.UpdateRandomeBall();
            }

        }
        private void CompletedWork_StartDemo(object sender, RunWorkerCompletedEventArgs e)
        {
            if (enableDemo)
            {
                guiWorker.RunWorkerAsync();
            }
            else
            {
                guiWorker.DoWork -= new DoWorkEventHandler(DoWork_StartDemo);
                guiWorker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(CompletedWork_StartDemo);
                EnableButtons(null);
            }
        }

        private void DoWork_StopDemo(object sender, EventArgs arguments)
        {
            enableDemo = false;
        }
        private void CompletedWork_StopDemo(object sender, RunWorkerCompletedEventArgs e)
        {
            guiWorker1.DoWork -= new DoWorkEventHandler(DoWork_StopDemo);
            guiWorker1.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(CompletedWork_StopDemo);
            
        }
        /// <summary>
        ///   Creates the "Make Group" and "Send Green" buttons directly on the desktop
        /// </summary>
        /// <param name="mainScreen">
        ///   Screen to whose desktop the buttons will be added
        /// </param>
        private void createDesktopControls(Screen mainScreen)
        {
            ButtonControl writeLogButton = new ButtonControl();
            writeLogButton.Text = "Write Log";
            writeLogButton.Bounds = new UniRectangle(
              new UniScalar(1.0f, -430.0f), new UniScalar(1.0f, -32.0f), 100, 32
            );
            writeLogButton.Pressed += delegate(object sender, EventArgs arguments)
            {
                guiWorker1.DoWork += new DoWorkEventHandler(DoWork_WriteLog);
                guiWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedWork_WriteLog);
                guiWorker1.RunWorkerAsync();

            };
            mainScreen.Desktop.Children.Add(writeLogButton);//index 0

            ButtonControl joinGroupButton = new ButtonControl();
            joinGroupButton.Text = "Make/Join Group";
            joinGroupButton.Bounds = new UniRectangle(
              new UniScalar(1.0f, -315.0f), new UniScalar(1.0f, -32.0f), 110, 32
            );
            joinGroupButton.Pressed += delegate(object sender, EventArgs arguments)
            {
                guiWorker.DoWork += new DoWorkEventHandler(DoWork_JoinIsisGroup);
                guiWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedWork_JoinIsisGroup);
                guiWorker.RunWorkerAsync();

            };
            mainScreen.Desktop.Children.Add(joinGroupButton);//index 1


            ButtonControl startButton = new ButtonControl();
            startButton.Text = "Start";
            startButton.Bounds = new UniRectangle(
              new UniScalar(1.0f, -190.0f), new UniScalar(1.0f, -32.0f), 100, 32
            );
            startButton.Pressed += delegate(object sender, EventArgs arguments)
            {
                guiWorker.DoWork += new DoWorkEventHandler(DoWork_StartDemo);
                guiWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedWork_StartDemo);
                guiWorker.RunWorkerAsync();
            };
            mainScreen.Desktop.Children.Add(startButton); //index 2

            ButtonControl stopButton = new ButtonControl();
            stopButton.Text = "Stop";
            stopButton.Bounds = new UniRectangle(
              new UniScalar(1.0f, -80.0f), new UniScalar(1.0f, -32.0f), 100, 32
            );
            stopButton.Pressed += delegate(object sender, EventArgs arguments)
            {
                guiWorker1.DoWork += new DoWorkEventHandler(DoWork_StopDemo);
                guiWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompletedWork_StopDemo);
                guiWorker1.RunWorkerAsync();
            };
            mainScreen.Desktop.Children.Add(stopButton); //index 3

           

        }
        private void DrawText()
        {
            string text = null;

            if (displayHelp)
            {
                System.Text.StringBuilder buffer = new System.Text.StringBuilder();
                buffer.AppendFormat("FPS: {0}\n", framesPerSecond);
                buffer.AppendFormat("Floor Technique: {0}\n\n",
                    (disableParallax ? "Normal mapping" : "Parallax normal mapping"));
                buffer.Append("Camera:\n");
                buffer.AppendFormat("  Behavior: {0}\n", camera.CurrentBehavior);
                buffer.AppendFormat("  Position: x:{0} y:{1} z:{2}\n",
                    camera.Position.X.ToString("#0.00"),
                    camera.Position.Y.ToString("#0.00"),
                    camera.Position.Z.ToString("#0.00"));
                buffer.AppendFormat("  Velocity: x:{0} y:{1} z:{2}\n",
                    camera.CurrentVelocity.X.ToString("#0.00"),
                    camera.CurrentVelocity.Y.ToString("#0.00"),
                    camera.CurrentVelocity.Z.ToString("#0.00"));
                buffer.AppendFormat("  Rotation speed: {0}\n",
                    camera.RotationSpeed.ToString("#0.00"));

                if (camera.PreferTargetYAxisOrbiting)
                    buffer.Append("  Target Y axis orbiting\n\n");
                else
                    buffer.Append("  Free orbiting\n\n");
                buffer.AppendLine("Press 1 to switch to first person behavior");
                buffer.AppendLine("Press 2 to switch to spectator behavior");
                buffer.AppendLine("Press 3 to switch to flight behavior");
                buffer.AppendLine("Press 4 to switch to orbit behavior");
                buffer.AppendLine();
                buffer.AppendLine("First Person and Spectator behaviors:");
                buffer.AppendLine("  Press W and S to move forwards and backwards");
                buffer.AppendLine("  Press A and D to strafe left and right");
                buffer.AppendLine("  Press E and Q to move up and down");
                buffer.AppendLine("  Move mouse to free look");
                buffer.AppendLine();
                buffer.AppendLine("Flight behavior:");
                buffer.AppendLine("  Press W and S to move forwards and backwards");
                buffer.AppendLine("  Press A and D to yaw left and right");
                buffer.AppendLine("  Press E and Q to move up and down");
                buffer.AppendLine("  Move mouse up and down to change pitch");
                buffer.AppendLine("  Move mouse left and right to change roll");
                buffer.AppendLine();
                buffer.AppendLine("Orbit behavior:");
                buffer.AppendLine("  Press SPACE to enable/disable target Y axis orbiting");
                buffer.AppendLine("  Move mouse to orbit the model");
                buffer.AppendLine("  Mouse wheel to zoom in and out");
                buffer.AppendLine();
                buffer.AppendLine("Press T to enable/disable floor textures");
                buffer.AppendLine("Press P to toggle between parallax normal mapping and normal mapping");
                buffer.AppendLine("Press C to toggle mouse click-and-drag camera rotation");
                buffer.AppendLine("Press BACKSPACE to level camera");
                buffer.AppendLine("Press NUMPAD +/- to change camera rotation speed");
                buffer.AppendLine("Press ALT + ENTER to toggle full screen");
                buffer.AppendLine("Press H to hide help");

                text = buffer.ToString();
            }
            else
            {
                System.Text.StringBuilder buffer = new System.Text.StringBuilder();

                buffer.AppendLine("Press O : original view");
                buffer.AppendLine("Press X : X axis view");
                buffer.AppendLine("Press Y : Y axis view");
                buffer.AppendLine("Press Z : Z axis view");
                buffer.AppendLine("Press H to see more detail help");

                text = buffer.ToString();
            }

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            spriteBatch.DrawString(spriteFont, text, fontPos, Color.Yellow);
            spriteBatch.End();
        }
        public void EnableButtons(int[] except)
        {

            for (int i = 0; i < mainScreen.Desktop.Children.Count; i++)
            {
                ((ButtonControl)mainScreen.Desktop.Children[i]).Enabled = true;
            }
            if (except != null)
            {
                for (int j = 0; j < except.Length; j++)
                {
                    ((ButtonControl)mainScreen.Desktop.Children[except[j]]).Enabled = false;
                }
            }
        }
        public void DisableButtons(int[] except)
        {
            for (int i = 0; i < mainScreen.Desktop.Children.Count; i++)
            {
                ((ButtonControl)mainScreen.Desktop.Children[i]).Enabled = false;
            }
            if (except != null)
            {
                for (int j = 0; j < except.Length; j++)
                {
                    ((ButtonControl)mainScreen.Desktop.Children[except[j]]).Enabled = true;
                }
            }
            
        }
        public int getMaxGroupNumber()
        {
            return maxRow * maxCol;
        }


    }

    
}
